/*------------------------------------------------------------------------*/
/* Unicode handling functions for FatFs R0.09                           */
/*------------------------------------------------------------------------*/

#include "ff.h"

#if _USE_LFN != 0

/*------------------------------------------------------------------------*/
/* Code conversion tables                                                */
/*------------------------------------------------------------------------*/

#if _CODE_PAGE == 1252	/* Latin 1 */
static
const WCHAR Tbl[] = {	/*  CP1252(0x80-0xFF) to Unicode conversion table */
	0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
	0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
	0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
	0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178,
	0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
	0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
	0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
	0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
	0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
	0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
	0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
	0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
	0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
	0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
	0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
	0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
};
#endif

/*------------------------------------------------------------------------*/
/* OEM <==> Unicode conversions                                          */
/*------------------------------------------------------------------------*/

WCHAR ff_convert (	/* Converted code, 0 means conversion error */
	WCHAR	chr,	/* Character code to be converted */
	UINT	dir		/* 0: OEM to Unicode, 1: Unicode to OEM */
)
{
	WCHAR c;

	if (chr < 0x80) {	/* ASCII */
		c = chr;

	} else {
		if (dir) {	/* Unicode to OEM */
			c = 0;
#if _CODE_PAGE == 1252
			if (chr >= 0x80 && chr <= 0xFF) {
				c = chr;
			} else {
				const WCHAR *p = Tbl;
				for (c = 0x80; c < 0x100; c++) {
					if (chr == *p++) break;
				}
				if (c >= 0x100) c = 0;
			}
#endif
		} else {		/* OEM to Unicode */
			c = 0;
#if _CODE_PAGE == 1252
			if (chr >= 0x80 && chr <= 0xFF) {
				c = Tbl[chr - 0x80];
			}
#endif
		}
	}

	return c;
}


WCHAR ff_wtoupper (	/* Upper converted character */
	WCHAR chr		/* Input character */
)
{
	static const WCHAR tbl_lower[] = {	/* Lower case characters to be converted */
		/* Latin Supplement */
		0x00E0,0x00E1,0x00E2,0x00E3,0x00E4,0x00E5,0x00E6,0x00E7,0x00E8,0x00E9,0x00EA,0x00EB,0x00EC,0x00ED,0x00EE,0x00EF,
		0x00F0,0x00F1,0x00F2,0x00F3,0x00F4,0x00F5,0x00F6,0x00F8,0x00F9,0x00FA,0x00FB,0x00FC,0x00FD,0x00FE,0x00FF,
		/* Latin Extended-A */
		0x0101,0x0103,0x0105,0x0107,0x0109,0x010B,0x010D,0x010F,0x0111,0x0113,0x0115,0x0117,0x0119,0x011B,0x011D,0x011F,
		0x0121,0x0123,0x0125,0x0127,0x0129,0x012B,0x012D,0x012F,0x0131,0x0133,0x0135,0x0137,0x013A,0x013C,0x013E,0x0140,
		0x0142,0x0144,0x0146,0x0148,0x014B,0x014D,0x014F,0x0151,0x0153,0x0155,0x0157,0x0159,0x015B,0x015D,0x015F,0x0161,
		0x0163,0x0165,0x0167,0x0169,0x016B,0x016D,0x016F,0x0171,0x0173,0x0175,0x0177,0x017A,0x017C,0x017E,
		0
	};
	static const WCHAR tbl_upper[] = {	/* Corresponding upper case characters */
		/* Latin Supplement */
		0x00C0,0x00C1,0x00C2,0x00C3,0x00C4,0x00C5,0x00C6,0x00C7,0x00C8,0x00C9,0x00CA,0x00CB,0x00CC,0x00CD,0x00CE,0x00CF,
		0x00D0,0x00D1,0x00D2,0x00D3,0x00D4,0x00D5,0x00D6,0x00D8,0x00D9,0x00DA,0x00DB,0x00DC,0x00DD,0x00DE,0x0178,
		/* Latin Extended-A */
		0x0100,0x0102,0x0104,0x0106,0x0108,0x010A,0x010C,0x010E,0x0110,0x0112,0x0114,0x0116,0x0118,0x011A,0x011C,0x011E,
		0x0120,0x0122,0x0124,0x0126,0x0128,0x012A,0x012C,0x012E,0x0049,0x0132,0x0134,0x0136,0x0139,0x013B,0x013D,0x013F,
		0x0141,0x0143,0x0145,0x0147,0x014A,0x014C,0x014E,0x0150,0x0152,0x0154,0x0156,0x0158,0x015A,0x015C,0x015E,0x0160,
		0x0162,0x0164,0x0166,0x0168,0x016A,0x016C,0x016E,0x0170,0x0172,0x0174,0x0176,0x0179,0x017B,0x017D,
		0
	};
	int i;

	if (chr < 0x80) {	/* ASCII characters */
		if (chr >= 'a' && chr <= 'z') {
			chr -= 0x20;
		}
	} else {			/* Extended characters */
		for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ;
		if (tbl_lower[i]) chr = tbl_upper[i];
	}

	return chr;
}

#endif /* _USE_LFN != 0 */
